/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *	  http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 package com.googlecode.milib.display.service {
	import com.googlecode.milib.display.button.AbstractButton;
	import com.googlecode.milib.display.button.views.ButtonViewContrast;
	import com.googlecode.milib.display.button.views.ButtonViewFourFrames;
	import com.googlecode.milib.display.button.views.ButtonViewGlow;
	import com.googlecode.milib.display.button.views.ButtonViewIniMidEnd;
	import com.googlecode.milib.display.button.views.ButtonViewPlayTo;

	import flash.display.FrameLabel;
	import flash.display.InteractiveObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	import flash.utils.Dictionary;

	/**
	 * @author Marek Brun
	 */
	public class MLButton extends AbstractButton {
		
		protected static const servicedObjects : Dictionary = new Dictionary(true);
		public var _btn:InteractiveObject;		

		/*
	click  Dispatched when a user presses and releases the main button of the user's pointing device over the same InteractiveObject. InteractiveObject 
	doubleClick  Dispatched when a user presses and releases the main button of a pointing device twice in rapid succession over the same InteractiveObject when that object's doubleClickEnabled flag is set to true. InteractiveObject	 
	mouseDown  Dispatched when a user presses the pointing device button over an InteractiveObject instance in the Flash Player window. InteractiveObject  
	mouseUp  Dispatched when a user releases the pointing device button over an InteractiveObject instance in the Flash Player window. InteractiveObject 
	mouseWheel  Dispatched when a mouse wheel is spun over an InteractiveObject instance in the Flash Player window. InteractiveObject 
	removed		   Dispatched when a display object is about to be removed from the display list. DisplayObject 
	removedFromStage  Dispatched when a display object is about to be removed from the display list, either directly or through the removal of a sub tree in which the display object is contained. DisplayObject 
	render  Dispatched when the display list is about to be updated and rendered. DisplayObject   
	mouseOut  Dispatched when the user moves a pointing device away from an InteractiveObject instance. InteractiveObject
	mouseOver  Dispatched when the user moves a pointing device over an InteractiveObject instance in the Flash Player window. InteractiveObject  
*/
		public function MLButton(acces:Private, btn:InteractiveObject) {
			_btn=btn;
			_btn.addEventListener(MouseEvent.CLICK, onBtnClick, false, 0, true);
			_btn.addEventListener(MouseEvent.MOUSE_DOWN, onBtnDown, false, 0, true);
			_btn.addEventListener(MouseEvent.MOUSE_UP, onBtnUp, false, 0, true);
			
			_btn.addEventListener(MouseEvent.ROLL_OVER, onBtnOver, false, 0, true);
			_btn.addEventListener(MouseEvent.ROLL_OUT, onBtnOut, false, 0, true);
			
			_btn.addEventListener(FocusEvent.FOCUS_IN, onBtnFocusIn, false, 0, true);
			_btn.addEventListener(FocusEvent.FOCUS_OUT, onBtnFocusOut, false, 0, true);
			_btn.addEventListener(Event.REMOVED_FROM_STAGE, onBtnRemovedFromStage, false, 0, true);
			_btn.tabEnabled=true;
			if(_btn is Sprite){
				Sprite(_btn).useHandCursor=true;
				Sprite(_btn).buttonMode=true;
				Sprite(_btn).mouseChildren=false;
				setupAutoView();
			}
			
		}
		
		override protected function doIsEnabled():void {
			btn.mouseEnabled=getIsEnabled();
		}
		
		public function disableButtonMode():void {
			if(_btn is Sprite){
				Sprite(_btn).useHandCursor=false;
				Sprite(_btn).buttonMode=false;
				Sprite(_btn).mouseChildren=true;
			}
		}
		
		public function enableButtonMode():void {
			if(_btn is Sprite){
				Sprite(_btn).useHandCursor=true;
				Sprite(_btn).buttonMode=true;
				Sprite(_btn).mouseChildren=false;
			}
		}
		
		public function get btn():InteractiveObject { return _btn; }
		
		/**
		 * <p>setupAutoView is working only if you name label in clip properly 
		 * Supported flags:
		 * 	- bv_4: ButtonViewFourFrames
		 * 	- bv_playTo: ButtonViewPlayTo		 * 	- bv_c: ButtonViewContrast		 * 	- bv_ime: ButtonViewIniMidEnd		 * 	- bv_g: ButtonViewGlow
		 * 	</p>
		 */
		public function setupAutoView():void {
			if(_btn is MovieClip){
				var mc:MovieClip=MovieClip(_btn);
				var mlmc:MLMC=MLMC.forInstance(mc);
				var i:uint;
				var loopLabel:FrameLabel, labelElements:Array;
				for(i=0;i<mc.currentLabels.length;i++){
					loopLabel=mc.currentLabels[i];
					labelElements=loopLabel.name.split('_');
					if(labelElements[0]=='bv'){
						if(labelElements[2]){
							if(mlmc.gotInstance(labelElements[2])){
								setupAutoViewByMCAndTypeID(mlmc.getMC(labelElements[2]), labelElements[1]);
							}else{
								throw new Error('Unable to find MovieClip '+labelElements[2]);
							}
						}else{
							setupAutoViewByMCAndTypeID(mc, labelElements[1]);
						}
					}
				}
			}
		}
		
		protected function setupAutoViewByMCAndTypeID(mc:MovieClip, typeID:String):void {
			switch(typeID){
				case '4':
					addButtonView(ButtonViewFourFrames.forInstance(mc));
				break;
				case 'playTo':
					addButtonView(ButtonViewPlayTo.forInstance(mc));
				break;
				case 'c':
					addButtonView(ButtonViewContrast.forInstance(mc));
				break;
				case 'g':
					addButtonView(ButtonViewGlow.forInstance(mc));
				break;
				case 'ime':
					addButtonView(ButtonViewIniMidEnd.forInstance(mc));
				break;
				default:
					throw new ArgumentError('Unexpected typeID walue ('+typeID+')');
			}
		}
		
		public static function forInstance(btn:InteractiveObject):MLButton {
			if(btn==null){
				throw Error("Value of passed argument 'btn' is null");
				return;
			}
			if(servicedObjects[btn]){
				return servicedObjects[btn];
			}else{
				servicedObjects[btn]=new MLButton(null, btn);
				return servicedObjects[btn];
			}
		}
		
		public static function createFromMCBoundBox(mc:MovieClip):MLButton {
			var btn:MovieClip=new MovieClip();
			var bounds:Rectangle=mc.getBounds(mc.parent);
			btn.graphics.beginFill(0x00FF00);
			btn.graphics.drawRect(0, 0, bounds.width, bounds.height);
			btn.graphics.endFill();
			btn.x=mc.x;
			btn.y=mc.y;
			mc.parent.addChild(btn);
			return forInstance(btn);
		}
		
//********************************************************************************************
//		events for MLButton
//********************************************************************************************
		protected function onMouseUp(event:Event):void {
			ms.removeEventListener(ms.event_Up, onMouseUp);
			setReleaseOutside();
		}
		
		protected function onBtnDown(event:MouseEvent):void {
			setPress();
		}
		
		protected function onBtnOut(event:MouseEvent):void {
			if(ms.getIsDown()){
				setDragOut();
				ms.addEventListener(ms.event_Up, onMouseUp);
			}else{
				setRollOut();
			}
		}
		
		protected function onBtnOver(event:MouseEvent):void {
			if(ms.getIsDown()){
				setDragOver();
			}else{
				setRollOver();
			}
		}
		
		protected function onBtnUp(event:MouseEvent):void {
			setRelease();
		}
		
		protected function onBtnFocusIn(event:FocusEvent):void {
			if(!getIsOver()){
				_btn.addEventListener(KeyboardEvent.KEY_DOWN, onBtnKeyDown, false, 0, true);
				setRollOver();
			}
		}
		
		protected function onBtnFocusOut(event:FocusEvent):void {
			if(getIsOver()){
				setRollOut();
			}
		}
		
		protected function onBtnKeyDown(event:KeyboardEvent):void {
			if(getIsOver() && event.keyCode==Keyboard.ENTER){
				setPress();
				_btn.addEventListener(KeyboardEvent.KEY_UP, onBtnKeyUp, false, 0, true);
			}
		}
		
		protected function onBtnKeyUp(event:KeyboardEvent):void {
			if(getIsPressed() && event.keyCode==Keyboard.ENTER){
				setRelease();
				_btn.removeEventListener(KeyboardEvent.KEY_UP, onBtnKeyUp);
			}
		}
		
		protected function onBtnClick(event:MouseEvent):void {
			
		}
		
		protected function onBtnRemovedFromStage(event:Event):void {
			//TODO doDelete
		}
	}
}

internal class Private {} 